package com.sfpay.coreplatform.order.service.impl;

import java.util.Date;
import java.util.concurrent.atomic.AtomicLong;
 

import javax.annotation.Resource;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;

import org.springframework.transaction.annotation.Transactional;

import com.sfpay.coreplatform.order.common.OrderResponseCode;

import com.sfpay.coreplatform.order.common.enums.TradeType; 
import com.sfpay.coreplatform.order.service.IPayService; 
import com.sfpay.coreplatform.order.service.composite.common.PayChannelHandlerFactory;
import com.sfpay.coreplatform.order.service.composite.common.PayContext;
import com.sfpay.coreplatform.order.service.composite.impl.AccountHandler;
import com.sfpay.coreplatform.order.service.composite.impl.CheckAccHandler;
import com.sfpay.coreplatform.order.service.composite.impl.CheckCancelHandler;
import com.sfpay.coreplatform.order.service.composite.impl.CheckParamHandler;
import com.sfpay.coreplatform.order.service.composite.impl.CheckRepeatHandler;
import com.sfpay.coreplatform.order.service.composite.impl.CheckReverseHandler;

import com.sfpay.coreplatform.order.service.composite.impl.TradePayHandler;
import com.sfpay.coreplatform.order.service.composite.impl.TradePayStatusHandler;
import com.sfpay.coreplatform.order.valueobject.dto.PayRequest;
import com.sfpay.coreplatform.order.valueobject.dto.PayTradeResponse;
import com.sfpay.coreplatform.order.valueobject.dto.Response;


@Service
public class PayServiceImpl implements IPayService {

	private final static Logger logger = LoggerFactory
			.getLogger(PayServiceImpl.class);

	@Resource
	private AccountHandler accountHandler;
	@Resource
	private CheckAccHandler checkAccHandler;
	@Resource
	private CheckParamHandler checkParamHandler;
	@Resource
	private CheckRepeatHandler checkRepeatHandler;
	@Resource
	private TradePayHandler tradePayHandler;
	@Resource
	private TradePayStatusHandler tradePayStatusHandler; 
	@Resource
	private CheckReverseHandler checkReverseHandler;
	@Resource
	private CheckCancelHandler checkCancelHandler;
	

	@Transactional
	public PayTradeResponse pay(PayRequest request) {

	   
		logger.info("---"+request.getOutTradeNo()+"---------------New Pay Begin "+request+"---------------");
		 
		PayTradeResponse returnResponse = new PayTradeResponse();

		PayChannelHandlerFactory payChannel = new PayChannelHandlerFactory();// 创建通道链

		payChannel.addHandler(checkParamHandler);// 检查参数
		payChannel.addHandler(checkRepeatHandler);// 检查并发
		payChannel.addHandler(checkAccHandler);// 检查账号
		payChannel.addHandler(tradePayHandler);// 交易支付处理
		payChannel.addHandler(accountHandler);// 账务处理
		payChannel.addHandler(tradePayStatusHandler);// 交易支付状态处理

		PayContext payContext = new PayContext();
		payContext.setTradeType(TradeType.PAY);
		Response response = payChannel.startHandler(request, payContext);// 开始执行

		checkRepeatHandler.removeOverCodeHandler(request.getOutTradeNo());// 去掉并发检查code;

		if (response.getReturnCode() < 0||response.getReturnCode()>10000) {

			returnResponse.setResponse(response);

		} else if (payContext.getAccCode() < 0) {// 账务处理失败
			returnResponse.setReturnCode(payContext.getAccCode());
			returnResponse.setReturnMsg(payContext.getAccMsg());
		}  else {		 
			returnResponse.setOrderNo(payContext.getTradeNo());
			returnResponse.setEndDate(new Date());
			returnResponse
					.setReturnCode(OrderResponseCode.ORDER_RESPONSE_SUCESS);

		}
		 logger.info("---"+request.getOutTradeNo()+"---------------New Pay end  ---------------");		 
		payContext = null;
		return returnResponse;

	}

	@Transactional
	public PayTradeResponse reversePay(Long platformMemberNo, String outTradeNo) {
		 
		PayRequest request=new PayRequest();		
		logger.info("---"+outTradeNo+"---------------New reversePay Begin "+platformMemberNo+":"+outTradeNo+"---------------");
		request.setPlatformMemberNo(platformMemberNo);
		request.setOutTradeNo(outTradeNo);
		PayTradeResponse returnResponse = new PayTradeResponse();		 
		PayChannelHandlerFactory payChannel = new PayChannelHandlerFactory();// 创建通道链

		payChannel.addHandler(checkRepeatHandler);// 检查并发
		payChannel.addHandler(checkReverseHandler);// 检查冲正
		payChannel.addHandler(tradePayHandler);// 交易支付处理
		payChannel.addHandler(accountHandler);// 账务处理
		payChannel.addHandler(tradePayStatusHandler);// 交易支付状态处理
		PayContext payContext = new PayContext();// 处理上下文
		payContext.setTradeType(TradeType.REVERSE);// 冲正
		Response response = payChannel.startHandler(request, payContext);// 开始执行

		checkRepeatHandler.removeOverCodeHandler(request.getOutTradeNo());// 去掉并发检查code;

		if (response.getReturnCode() < 0||response.getReturnCode()>10000) {
			returnResponse.setResponse(response);
		} else if (payContext.getAccCode() < 0) {// 账务处理失败
			returnResponse.setReturnCode(payContext.getAccCode());
			returnResponse.setReturnMsg(payContext.getAccMsg());
		} else {
			returnResponse.setOrderNo(payContext.getTradeNo());
			returnResponse.setEndDate(new Date());
			returnResponse
					.setReturnCode(OrderResponseCode.ORDER_RESPONSE_SUCESS);
			returnResponse.setReturnMsg("method:reversePay businessNo:"
					+ outTradeNo + "  reverse success");
		}
		logger.info("---"+outTradeNo+"---------------New reversePay end  ---------------");
		request = null;
		payContext = null;		 
		return returnResponse;
	}

 

	@Transactional
	public PayTradeResponse cancelPay(PayRequest request) {
		 
		logger.info("---"+request.getOutTradeNo()+"---------------New cancelPay Begin "+request+"---------------");
		PayTradeResponse returnResponse = new PayTradeResponse();
	 
		PayChannelHandlerFactory payChannel = new PayChannelHandlerFactory();// 创建通道链

		payChannel.addHandler(checkParamHandler);// 检查参数
		payChannel.addHandler(checkRepeatHandler);// 检查并发
		payChannel.addHandler(checkCancelHandler);//检查撤消
		payChannel.addHandler(checkAccHandler);// 检查账号		
		payChannel.addHandler(tradePayHandler);// 交易支付处理
		payChannel.addHandler(accountHandler);// 账务处理
		payChannel.addHandler(tradePayStatusHandler);// 交易支付状态处理

		PayContext payContext = new PayContext();// 处理上下文
		payContext.setTradeType(TradeType.CANCEL);// 撤消
		Response response = payChannel.startHandler(request, payContext);// 开始执行

		checkRepeatHandler.removeOverCodeHandler(request.getOutTradeNo());// 去掉并发检查code;

		if (response.getReturnCode() < 0||response.getReturnCode()>10000) {
			returnResponse.setResponse(response);
		} else if (payContext.getAccCode() < 0) {// 账务处理失败
			returnResponse.setReturnCode(payContext.getAccCode());
			returnResponse.setReturnMsg(payContext.getAccMsg());
		} else {
			returnResponse.setOrderNo(payContext.getTradeNo());
			returnResponse.setEndDate(new Date());
			returnResponse
					.setReturnCode(OrderResponseCode.ORDER_RESPONSE_SUCESS);
			returnResponse.setReturnMsg("method:cancelPay businessNo:"
					+ request.getOutTradeNo() + "  cancel success");
		}
		logger.info("---"+request.getOutTradeNo()+"---------------New cancelPay end  ---------------");		 
		payContext = null;		
		return returnResponse;
	}

	 

}
